<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ page import="nus.edu.sg.servlet.RequestConstants"%>
<%@ page import="nus.edu.sg.object.ParameterConstant"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>Database Performance Dashboard</title>
<link rel="stylesheet" href="css/normalize.css" />
<link rel="stylesheet" href="css/foundation.css" />
<link rel="stylesheet" href="css/custom.css" />
<link rel="stylesheet" href="css/datetimepicker.css" />
<script src="js/vendor/custom.modernizr.js"></script>
<script src="js/vendor/jquery.js"></script>
<script src="js/vendor/bootstrap-datetimepicker.min.js"></script>
<script src="js/foundation/foundation.js"></script>
<script src="js/foundation/foundation-datepicker.js"></script>
<script src="js/foundation/foundation.dropdown.js"></script>
<script src="js/foundation/foundation.tooltips.js"></script>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
</head>
<body>
	<%@include file="topbar.jsp"%>
	<%@include file="performance.jsp"%>
	<%@include file="config.jsp"%>
	<%@include file="report.jsp"%>
	<%@include file="console.jsp"%>
</body>
<%
	String ajaxUrl = "db_tune";
%>
<script>
	var monthNames = [ "January", "February", "March", "April", "May", "June",
                   "July", "August", "September", "October", "November", "December" ];
	var google_ready = false; /* whether the google js library is ready */
	var millisecond = 1000; /* milliseconds in a second */
	var second = 60; /* seconds in a minute */
	var minute = 60; /* minutes in a hour */
	var hour = 24; /* hours in a day */
	google.load("visualization", "1", {packages:["corechart"]});
	google.setOnLoadCallback(function(){
		google_ready = true;
	});
	$(document).foundation();
	$(document).ready(function() {
		var threshold = [[0, 0],[0, 0],[0, 0],[0, 0]];
		
		/* get time range selection in performance tab */
		var get_time_range = function() {
			var currentTime = new Date().getTime();
			var startTime = currentTime - hour * minute * second * millisecond;
			var endTime = currentTime;
			var filter1 = $('.performance .filter1 dd').index($('.performance .filter1 .active'));
			if (filter1 == 1) {
				var current_filter = $('.performance .filter2 .active');
				var end = endTime - parseInt(current_filter.find('.filter_min').html()) * second * millisecond;
				var start = endTime - parseInt(current_filter.find('.filter_max').html()) * second * millisecond;
				startTime = start;
				endTime = end;
			} else if (filter1 == 2) {
				var current_filter = $('.performance .filter3 .active');
				var end = endTime - parseInt(current_filter.find('.filter_min').html()) * second * millisecond;
				var start = endTime - parseInt(current_filter.find('.filter_max').html()) * second * millisecond;
				startTime = start;
				endTime = end;
			}
			return [startTime, endTime];
		};
		
		/* display performance aggregate values */
		var poll_result = function() {
			var timeRange = get_time_range();
			var startTime = new Date(timeRange[0]);
			var endTime = new Date(timeRange[1]);
			var startTimeString = monthNames[startTime.getMonth()] + '-' + startTime.getDate() + ' ' + startTime.getHours() + ':' + startTime.getMinutes() + ':' + startTime.getSeconds();
			var endTimeString = monthNames[endTime.getMonth()] + '-' + endTime.getDate() + ' ' + endTime.getHours() + ':' + endTime.getMinutes() + ':' + endTime.getSeconds();
			$('.performance .time_label .start').html(startTimeString);
			$('.performance .time_label .end').html(endTimeString);
			$.ajax({
				url: '<%=ajaxUrl%>',
				data: {
					cmd: '<%=RequestConstants.PERFORMANCE%>',
					<%=RequestConstants.START_TIME%>: timeRange[0],
					<%=RequestConstants.END_TIME%>: timeRange[1]
				},
				dataType: 'json',
				success: function(data) {
					if (data.error != undefined) {
						console.log(data.error);
					} else {
						var timeRange = get_time_range();
						var currentTime = new Date().getTime();
						var thirty_minutes = 30 * second * millisecond;
						if (timeRange[1] + thirty_minutes > currentTime) {
							timeRange[1] -= thirty_minutes;
							timeRange[0] -= thirty_minutes;
						}
						$.ajax({
							url: '<%=ajaxUrl%>',
				            data: {
				            	cmd: '<%=RequestConstants.AWR_REPORT%>',
				            	<%=RequestConstants.START_TIME%>: timeRange[0],
								<%=RequestConstants.END_TIME%>: timeRange[1]
				            },
				            dataType: 'json',
				            success: function(data) {
				            	if (data.error != undefined) {
				            		$('.performance .awr_report').html(data.error);
				            		$('.performance .awr_report').show();
				            	} else {
				            		if (data.awr == undefined) {
				            			$('.performance .awr_report').hide();
				            		} else if (data.awr.length == 0) {
				            			$('.performance .awr_report').hide();
				            		} else {
				            			$('.performance .awr_report').html(data.awr);
				            			$('.performance .awr_report').show();
				            		}
				            	}
				            }
						});
						for (var i = 0; i < data.values.length; i++) {
							var span = $($('.performance .progress .meter').get(i));
							var percent = data.values[i];
							if (percent > 100) {
								percent = 100;
							}
							span.css('width', percent + '%');
							var div = span.parent();
							div.removeClass('success warning alert');
							span.html(data.values[i] + '%');
							if (data.values[i] < threshold[i][0])  {
								div.addClass('success');
							} else if (data.values[i] < threshold[i][1]) {
								div.addClass('warning');
							} else {
								div.addClass('alert');
								var range = get_time_range();
								var param_id = '<%=ParameterConstant.PARAM_SHARED_POOL_SIZE%>';
								if (i == 0) {
									param_id = '<%=ParameterConstant.PARAM_SHARED_POOL_SIZE%>';
								} else if (i == 1) {
									param_id = '<%=ParameterConstant.PARAM_BUFFER_CACHE%>';
								} else if (i == 2) {
									param_id = '<%=ParameterConstant.PARAM_REDO_LOG_BUFFER%>';
								} else if (i == 3) {
									param_id = '<%=ParameterConstant.PARAM_MEM_AREAR_FOR_SORTING%>';
								}
								$.ajax({
									url: '<%=ajaxUrl%>',
						            data: {
						            	cmd: '<%=RequestConstants.ADVICE%>',
						            	<%=RequestConstants.TIME_STAMP%>: (range[0] + range[1]) / 2,
						            	<%=RequestConstants.PARAM_ID%>: param_id,
						            	<%=RequestConstants.INDEX%>: i,
						            	<%=RequestConstants.VALUE%>: span.html()
						            },
						            dataType: 'json',
						            success : function(data) {
						            	if (data.error != undefined) {
						            		alert(data.error);
						            	} else {
						            		$($('.performance .progress .meter').get(data.index)).html('<span data-tooltip class="has-tip" title="' + data.advice + '">' + data.value + '</span>');
						            	}
						            }
								});
							}
						}
					}
				}
			});
		};
		
		var get_time_selection = function() {
			var start = parseInt($('.report .start_date').html()) - 8 * minute * second * millisecond;
			var end = parseInt($('.report .end_date').html()) - 8 * minute * second * millisecond;
			return [start, end];
		};
		/* display graph chart on breakdown values */
		var display_graph = function(level, type, param_id) {
			var timeRange = get_time_range();
			if (type == 'line') {
				timeRange = get_time_selection();
			}
			$.ajax({
				url: '<%=ajaxUrl%>',
				data: {
					cmd: '<%=RequestConstants.PERFORMANCE%>',
					<%=RequestConstants.START_TIME%>: timeRange[0],
					<%=RequestConstants.END_TIME%>: timeRange[1],
					<%=RequestConstants.LEVEL%>: level,
					<%=RequestConstants.PARAM_ID%>: param_id
				},
				dataType: 'json',
				success: function(data) {
					if (data.error != undefined) {
						if (type == 'bar') {
							$('#chart_div').hide();
						} else if (type == 'line') {
							$('#line_div').hide();
						}
					} else if (google_ready) {
						if (data.matrix.length > 1) {
							var google_data = google.visualization.arrayToDataTable(data.matrix);
							var options = {
							    title: 'Performance Breakdown',
							    hAxis: {title: 'Timestamp', titleTextStyle: {color: 'red'}},
							    chartArea: {width:"70%",height:"70%"}
							};
							if (type == 'bar') {
								var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
								chart.draw(google_data, options);
								$('#chart_div').show();
							} else if (type == 'line') {
								var chart = new google.visualization.LineChart(document.getElementById('line_div'));
								chart.draw(google_data, options);
								$('#line_div').show();
							}
						} else {
							if (type == 'bar') {
								$('#chart_div').hide();
							} else if (type == 'line') {
								$('#line_div').hide();
							}
						}
					}
				}
			});
		};
		
		/* build filtering buttons */
		var init_filtering = function() {
			$.ajax({
				url: '<%=ajaxUrl%>',
	            data: {
	            	cmd: '<%=RequestConstants.PARAM_GETTING%>',
	            },
	            dataType: 'json',
	            success : function(data) {
	            	$('.performance .level1').html(data.x + ' minutes block');
	            	$('.performance .level2').html(data.y + ' minutes block');
	            	var total_x = hour * minute / data.x;
	            	var total_y = data.x / data.y;
	            	for (var i = 0; i < total_x; i++) {
	            		if (i == 0) {
	            			$('.performance .filter2').append('<dd class="active"><a href="#"><span style="display:none;" class="filter_min">' + (i * data.x) + '</span>Block ' + (i + 1) + '<span style="display:none;" class="filter_max">' + (i + 1) * data.x + '</span></a></dd>');
	            		} else {
	            			$('.performance .filter2').append('<dd><a href="#"><span style="display:none;" class="filter_min">' + (i * data.x) + '</span>Block ' + (i + 1) + '<span style="display:none;" class="filter_max">' + (i + 1) * data.x + '</span></a></dd>');	
	            		}
	            	}
	            	for (var i = 0; i < total_y; i++) {
	            		if (i == 0) {
	            			$('.performance .filter3').append('<dd class="active"><a href="#"><span style="display:none;" class="filter_min">' + (i * data.y) + '</span>Block ' + (i + 1) + '<span style="display:none;" class="filter_max">' + (i + 1) * data.y + '</span></a></dd>');
	            		} else {
	            			$('.performance .filter3').append('<dd><a href="#"><span style="display:none;" class="filter_min">' + (i * data.y) + '</span>Block ' + (i + 1) + '<span style="display:none;" class="filter_max">' + (i + 1) * data.y + '</span></a></dd>');
	            		}
	            	}
	            	/* add event listeners for filtering buttons */
	            	$('.performance dd a').click(function(e) {
	            		e.preventDefault();
	            		$(this).closest('.sub-nav').children('dd').removeClass();
	        			$(this).parent().addClass('active');
	        			var index = $('.performance .filter1 a').index($(this));
	        			if (index == 0) {
	        				$('.performance .filter2').css('visibility', 'hidden');
	        				$('.performance .filter3').css('visibility', 'hidden');
	        				level = '<%=ParameterConstant.BREAK_DOWN_LEVEL_ONE%>';
	        			} else if (index == 1) {
	        				$('.performance .filter2').css('visibility', 'visible');
	        				$('.performance .filter3').css('visibility', 'hidden');
	        				level = '<%=ParameterConstant.BREAK_DOWN_LEVEL_TWO%>';
	        			} else if (index == 2) {
	        				$('.performance .filter2').css('visibility', 'visible');
	        				$('.performance .filter3').css('visibility', 'visible');
	        				level = '<%=ParameterConstant.BREAK_DOWN_LEVEL_THREE%>';
	        			}
	        			var filter2_index = $('.performance .filter2 a').index($(this));
	        			if (filter2_index != -1) {
	        				var base = parseInt($(this).find('.filter_min').html());
	        				$('.performance .filter3 a').each(function(index, node) {
	        					$(node).find('.filter_min').html(base + index * data.y);
	        					$(node).find('.filter_max').html(base + (index + 1) * data.y);
	        				});
	        			}
	        			poll_result();
	        			display_graph($('.filter1 dd').index($('.filter1 .active')), 'bar');
	        		});
	            }
			});
		};
		/* add listener for navigation buttons */
		var init_navigation = function() {
			$('.top-bar-section .top-navi>li>a').click(function(event) {
				event.preventDefault();
				$('.top-bar-section .top-navi>li').removeClass('active');
				$(this).closest('li').addClass('active');
				$('.content_div').hide();
				if ($(this).hasClass('performance-nav')) {
					$('.performance').show();
				}
				if ($(this).hasClass('threshold-nav')) {
					$('.config').show();
				}
				if ($(this).hasClass('report-nav')) {
					$('.report').show();
				}
				if ($(this).hasClass('console-nav')) {
					$('.console').show();
				}
			});
		};
		
		var init_xyz = function() {
			$.ajax({
				url: '<%=ajaxUrl%>',
	            data: {
	            	cmd: '<%=RequestConstants.PARAM_GETTING%>',
	            },
	            dataType: 'json',
	            success : function(data) {
	            	if (data.error != undefined) {
	            		alert(data.error);
	            	} else {
	            		$('.x_param').val(data.<%=RequestConstants.PARAM_X%>);
	            		$('.x_param').closest('.collapse').find('.value').val(data.<%=RequestConstants.PARAM_X%>);
	            		$('.y_param').val(data.<%=RequestConstants.PARAM_Y%>);
	            		$('.y_param').closest('.collapse').find('.value').val(data.<%=RequestConstants.PARAM_Y%>);
	            		$('.z_param').val(data.<%=RequestConstants.PARAM_Z%>);
	            		$('.z_param').closest('.collapse').find('.value').val(data.<%=RequestConstants.PARAM_Z%>);
	            	}
	            }
			});
		};
		/* set the threshold values for the parameters */
		var init_threshold = function() {
			$.ajax({
				url: '<%=ajaxUrl%>',
	            data: {
	            	cmd: '<%=RequestConstants.THRESHOLD_GETTING%>',
	            },
	            dataType: 'json',
	            success : function(data) {
	            	if (data.error != undefined) {
	            		alert(data.error);
	            	} else {
	            		$('.sp_min').val(data.<%=RequestConstants.SHARE_POOL_MIN%>);
	            		threshold[0][0] = parseInt(data.<%=RequestConstants.SHARE_POOL_MIN%>);
	            		$('.sp_min').closest('.collapse').find('.value').val(data.<%=RequestConstants.SHARE_POOL_MIN%>);
						$('.sp_max').val(data.<%=RequestConstants.SHARE_POOL_MAX%>);
						threshold[0][1] = parseInt(data.<%=RequestConstants.SHARE_POOL_MAX%>);
						$('.sp_max').closest('.collapse').find('.value').val(data.<%=RequestConstants.SHARE_POOL_MAX%>);
						$('.bc_min').val(data.<%=RequestConstants.BUFFERED_CACHE_MIN%>);
						threshold[1][0] = parseInt(data.<%=RequestConstants.BUFFERED_CACHE_MIN%>);
						$('.bc_min').closest('.collapse').find('.value').val(data.<%=RequestConstants.BUFFERED_CACHE_MIN%>);
						$('.bc_max').val(data.<%=RequestConstants.BUFFERED_CACHE_MAX%>);
						threshold[1][1] = parseInt(data.<%=RequestConstants.BUFFERED_CACHE_MAX%>);
						$('.bc_max').closest('.collapse').find('.value').val(data.<%=RequestConstants.BUFFERED_CACHE_MAX%>);
						$('.rlb_min').val(data.<%=RequestConstants.REDO_LOG_BUFFER_MIN%>);
						threshold[2][0] = parseInt(data.<%=RequestConstants.REDO_LOG_BUFFER_MIN%>);
						$('.rlb_min').closest('.collapse').find('.value').val(data.<%=RequestConstants.REDO_LOG_BUFFER_MIN%>);
						$('.rlb_max').val(data.<%=RequestConstants.REDO_LOG_BUFFER_MAX%>);
						threshold[2][1] = parseInt(data.<%=RequestConstants.REDO_LOG_BUFFER_MAX%>);
						$('.rlb_max').closest('.collapse').find('.value').val(data.<%=RequestConstants.REDO_LOG_BUFFER_MAX%>);
						$('.ms_min').val(data.<%=RequestConstants.MEMORY_SORTING_MIN%>);
						threshold[3][0] = parseInt(data.<%=RequestConstants.MEMORY_SORTING_MIN%>);
						$('.ms_min').closest('.collapse').find('.value').val(data.<%=RequestConstants.MEMORY_SORTING_MIN%>);
						$('.ms_max').val(data.<%=RequestConstants.MEMORY_SORTING_MAX%>);
						threshold[3][1] = parseInt(data.<%=RequestConstants.MEMORY_SORTING_MAX%>);
						$('.ms_max').closest('.collapse').find('.value').val(data.<%=RequestConstants.MEMORY_SORTING_MAX%>);
						poll_result();
						display_graph($('.filter1 dd').index('.filter1 .active'), 'bar');
	            	}
	            }
			});
		};
		/* setup listener for console tab */
		var setup_console_listener = function() {
			$('.sql_debug').click(function() {
				console.log($('.sql_command').val());
				$.ajax({
		            url: '<%=ajaxUrl%>',
		            data: {
		            	cmd: '<%=RequestConstants.SQL_DEBUG%>',
		                <%=RequestConstants.SQL_COMMAND%>: $('.sql_command').val()
		            },
		            dataType: 'json',
		            success : function(data) {
		            	if (data.error != undefined) {
		            		$('.console .alert-box').html(data.error);
		            		$('.console .alert-box').removeClass('success alert');
		            		$('.console .alert-box').addClass('alert');
		            		$('.console .alert-box').show();
		            	} else {
		            		var rows = data.rows;
		            		var rows_data = [];
		            		$('.console .panel').html('');
		            		if (rows.length == 1) {
		            			$('.console .panel').append(rows[0][0]);
		            		} else {
		            			for (var i = 0; i < rows.length; i++) {
				            		var row = '<tr>';
				            		if (i == 0) {
				            			row = '<thead><tr>';
				            		}
				            		for (var j = 0; j < rows[i].length; j++) {
				            			row += '<td>' + rows[i][j] + '</td>';
				            		}
				            		row += '</tr>';
				            		if (i == 0) {
				            			row += '</thead><tbody>';
				            		}
				            		if (i == rows.length - 1) {
				            			row += '</tbody>';
				            		}
				            		rows_data.push(row);
				            	}
				            	var table = $('<table/>').append(rows_data.join(' '));
				            	$('.console .panel').append(table);
		            		}
		            	}
		            }
		        });
			});
		};
		
		/* set listeners for configuration tab */
		var setup_config_listener = function() {
			/* set x, y, z values */
			$('.config .xyz').click(function() {
				$.ajax({
					url: '<%=ajaxUrl%>',
					data: {
						cmd: '<%=RequestConstants.PARAM_SETTING%>',
						<%=RequestConstants.PARAM_X%>: $('.x_param').val(),
						<%=RequestConstants.PARAM_Y%>: $('.y_param').val(),
						<%=RequestConstants.PARAM_Z%>: $('.z_param').val()
					},
					dataType: 'json',
					success : function(data) {
						$('.config .alert-box').removeClass('success alert');
	            		$('.config .alert-box').show();
						if (data.error != undefined) {
							$('.config .alert-box').html(data.error);
		            		$('.config .alert-box').addClass('alert');
		            	} else {
		            		$('.config .alert-box').html("XYZ configuration save successfully");
		            		$('.config .alert-box').addClass('success');
		            	}
					}
				});
			});
			/* setup threshold values */
			$('.config .threshold').click(function() {
				$.ajax({
					url: '<%=ajaxUrl%>',
					data: {
						cmd: '<%=RequestConstants.THRESHOLD_SETTING%>',
						<%=RequestConstants.SHARE_POOL_MIN%>: $('.sp_min').val(),
						<%=RequestConstants.SHARE_POOL_MAX%>: $('.sp_max').val(),
						<%=RequestConstants.BUFFERED_CACHE_MIN%>: $('.bc_min').val(),
						<%=RequestConstants.BUFFERED_CACHE_MAX%>: $('.bc_max').val(),
						<%=RequestConstants.REDO_LOG_BUFFER_MIN%>: $('.rlb_min').val(),
						<%=RequestConstants.REDO_LOG_BUFFER_MAX%>: $('.rlb_max').val(),
						<%=RequestConstants.MEMORY_SORTING_MIN%>: $('.ms_min').val(),
						<%=RequestConstants.MEMORY_SORTING_MAX%>: $('.ms_max').val()
					},
					dataType: 'json',
					success : function(data) {
						$('.config .alert-box').removeClass('success alert');
	            		$('.config .alert-box').show();
						if (data.error != undefined) {
							$('.config .alert-box').html(data.error);
		            		$('.config .alert-box').addClass('alert');
		            	} else {
		            		$('.config .alert-box').html("Threshold configuration save successfully");
		            		$('.config .alert-box').addClass('success');
		            	}
						init_threshold();
					}
				});
			});
			$('.config input').each(function() {
				if ($(this).attr('type') == 'range') {
					$(this).closest('.collapse').find('.value').val(this.value);
				}
			});
			$('.config input').change(function() {
				if ($(this).attr('type') == 'range') {
					$(this).closest('.collapse').find('.value').val(this.value);
				}
			});
		};
		/* setup listeners for performance tab */
		var setup_perform_listener = function() {
			$('.meter').css('cursor', 'pointer');
			$('.meter').click(function(e) {
				e.preventDefault();
				var param_id = '<%=ParameterConstant.PARAM_SHARED_POOL_SIZE%>';
				var param_index = $('.meter').index($(this));
				if (param_index == 0) {
					param_id = '<%=ParameterConstant.PARAM_SHARED_POOL_SIZE%>';
				} else if (param_index == 1) {
					param_id = '<%=ParameterConstant.PARAM_BUFFER_CACHE%>';
				} else if (param_index == 2) {
					param_id = '<%=ParameterConstant.PARAM_REDO_LOG_BUFFER%>';
				} else if (param_index == 3) {
					param_id = '<%=ParameterConstant.PARAM_MEM_AREAR_FOR_SORTING%>';
				}
				var filter_index = 0;
				$('.filter1 dd').each(function(index, node) {
					if ($(node).hasClass('active')) {
						filter_index = index;
					}
				});
				display_graph(filter_index, 'bar', param_id);
			});
		};
		
		/* setup listener for report tab */
		var setup_report_listener = function() {
			$('.dp1').datetimepicker({
		        weekStart: 1,
		        todayBtn:  1,
				autoclose: 1,
				todayHighlight: 1,
				startView: 2,
				forceParse: 0,
		        showMeridian: 1
		    }).on('changeDate', function(ev){
		    	$('.report .start_date').html(ev.date.valueOf());
		    });
			$('.dp2').datetimepicker({
		        weekStart: 1,
		        todayBtn:  1,
				autoclose: 1,
				todayHighlight: 1,
				startView: 2,
				forceParse: 0,
		        showMeridian: 1
		    }).on('changeDate', function(ev){
		    	$('.report .end_date').html(ev.date.valueOf());
		    });
			$('.report .f-dropdown a').click(function(e) {
				e.preventDefault();
				var paramId = $(this).attr('class');
				if (paramId != 'all_param') {
					display_graph(2, 'line', paramId);
				} else {
					display_graph(2, 'line');
				}
			});
		};
		var setup_event_listeners = function() {
			setup_console_listener();
			setup_config_listener();
			setup_perform_listener();
			setup_report_listener();
		};
		var init = function() {
			init_filtering();
			init_navigation();
			init_threshold();
			init_xyz();
			setup_event_listeners();
		};
		init();
	});
</script>
</html>